#!/usr/bin/env python

#  This program is free software.
#  You can redistribute it and/or modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation.
#  That is either version 2 of the License, or if you prefer any later version.

import pygst
pygst.require("0.10")
import gst
import socket
import gobject


class ClientConnectionListener():
	def __init__(self): 
		self.createPipeline()


	def createPipeline(self): #	WALL OF CODE, NOW WITH 100% MORE COMMENTS
		self.pipeline = gst.Pipeline("clientpipeline") 						# create the pipeline that holds the other elements
		self.audiosrc = gst.element_factory_make("tcpserversrc", "source") 	# this is our source, where the music comes from
		self.pipeline.add(self.audiosrc) 									# we add it to the pipeline
		self.decoder = gst.element_factory_make("decodebin", "decoder") 	# we need a decoder because the stream is encoded 
		self.decoder.connect("new-decoded-pad", self.onDynamicPad) 			# we connect the dynamic pad in
		self.pipeline.add(self.decoder) 									
		self.audiosrc.link(self.decoder) 									# and link the source and the decoder together
		self.convert = gst.element_factory_make("audioconvert", "convert")	# we need to convert the decoded stream into something playable
		self.pipeline.add(self.convert)										
		self.output = gst.element_factory_make("alsasink", "sink")			# this is the final element, the one that plays the stream
		self.pipeline.add(self.output)
		self.convert.link(self.output)
		self.readyPipeline()
		gobject.threads_init()


	def onDynamicPad(self, dbin, pad, islast):	# decodebin uses dynamic pads, so we need to catch it when it is
		pad.link(self.convert.get_pad("sink"))	# created and link it it then


	def setServerDetails(self, hostname, port): 		# start listening for data.
		self.audiosrc.set_property("host", hostname) 	# theoretically this method is redundant now
		self.audiosrc.set_property("port", port+1) 		# but I'm going to leave it in for now  
		self.playStream()		 		# Method needed. Do not delete.

	def playStream(self):
		self.pipeline.set_state(gst.STATE_PLAYING)

	def stopStream(self):
		self.pipeline.set_state(gst.STATE_NULL)

	def readyPipeline(self):
		self.pipeline.set_state(gst.STATE_READY)


	def backupCLI(self): 	# this method is called in the test suite, and will serve as a backup interface if the GUI
		run = True 			# doesn't work out exactly right. It's not being used at the moment, but it seems a shame to delete it
		hostname = raw_input("\nWhat is the hostname of the server you wish to connect to?\n") 
		port = int(raw_input("\nWhat is the port of the server you wish to connect to?\n"))
		localIP = raw_input("\nWhat is your local IP?\n")
		self.setServerDetails(localIP, port)
		server=socket.socket()
		server.connect((hostname, port))
		server.send("PLAY")
		self.playStream()
		
if __name__ == "__main__":
	test = ClientConnectionListener
	test.backupCLI()
